package study.springboot.mvc.support.advice;

import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;

import java.io.IOException;
import java.lang.reflect.Type;

@Slf4j
@RestControllerAdvice
public class GlobalRequestBodyAdvice extends RequestBodyAdviceAdapter {

    @Override
    public boolean supports(MethodParameter parameter,
                            Type targetType,
                            Class<? extends HttpMessageConverter<?>> converterType) {
        //判断是否有此注解，只有为true时才会执行afterBodyRead
        boolean f = parameter.getParameterAnnotation(RequestBody.class) != null;
        return f;
    }

    /**
     * Body 读之前
     */
    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage,
                                           MethodParameter parameter,
                                           Type targetType,
                                           Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
        log.info(">>>>>> beforeBodyRead");
        return super.beforeBodyRead(inputMessage, parameter, targetType, converterType);
    }

    /**
     * Body 读之后
     *
     * @param body          -Object
     * @param inputMessage  -HttpInputMessage
     * @param parameter     -MethodParameter
     * @param targetType    -Type
     * @param converterType -Class
     */
    @Override
    public Object afterBodyRead(Object body,
                                HttpInputMessage inputMessage,
                                MethodParameter parameter,
                                Type targetType,
                                Class<? extends HttpMessageConverter<?>> converterType) {
        log.info(">>>>>> afterBodyRead");
        log.info("i: {}", JSONUtil.toJsonStr(body));
        return super.afterBodyRead(body, inputMessage, parameter, targetType, converterType);
    }

    /**
     * 处理 Empty Body
     *
     * @param body          -Object
     * @param inputMessage  -HttpInputMessage
     * @param parameter     -MethodParameter
     * @param targetType    -Type
     * @param converterType -Class
     */
    @Override
    public Object handleEmptyBody(Object body,
                                  HttpInputMessage inputMessage,
                                  MethodParameter parameter,
                                  Type targetType,
                                  Class<? extends HttpMessageConverter<?>> converterType) {
        log.info(">>>>>> handleEmptyBody");
        return super.handleEmptyBody(body, inputMessage, parameter, targetType, converterType);
    }
}
